#include "UserModel.h"
#include "../../include/json/json.h"
#include <cstdlib>

namespace NET{
    UserModel::UserModel(){
        this->conn = new ClientNet();
        this->conn->connect();
        this->isDebug = false;
    }

    UserModel::~UserModel(){
        delete this->conn;
    }

    clientReturnStruct UserModel::registe(std::string username, std::string password){
        Json::Value root;
        Json::Value data;
        root["route"] = "user/registe";
        data["username"] = username;
        data["password"] = password;
        root["data"] = data;

        Json::StreamWriterBuilder builder;
        const std::string jsonString = Json::writeString(builder, root);

        int returnCode = this->conn->sendMsg(jsonString);

        if(returnCode == -1){
            return this->_echoClient(NET::CLIENT_ERROR_SEND_FAILED, "发送失败");
        }else{
            return this->_echoClient(NET::CLIENT_ERROR_SUCCESS, "success");
        }
    }

    clientReturnStruct UserModel::login(int uid, std::string password){
        Json::Value root;
        Json::Value data;
        root["route"] = "user/login";
        data["uid"] = uid;
        data["password"] = password;
        root["data"] = data;

        Json::StreamWriterBuilder builder;
        const std::string jsonString = Json::writeString(builder, root);

        int returnCode = this->conn->sendMsg(jsonString);

        if(returnCode == -1){
            return this->_echoClient(NET::CLIENT_ERROR_SEND_FAILED, "发送失败");
        }else{
            return this->_echoClient(NET::CLIENT_ERROR_SUCCESS, "success");
        }
    }

    clientReturnStruct UserModel::addFriend(int beuid){
        if(this->uid <= 0){
            return this->_echoClient(NET::CLIENT_ERROR_UNLOGIN, "请先登录");
        }
        
        Json::Value root, data;
        root["route"] = "user/addFriend";
        data["uid"] = this->uid;
        data["beuid"] = beuid;
        root["data"] = data;

        Json::StreamWriterBuilder builder;
        const std::string jsonString = Json::writeString(builder, root);

        int returnCode = this->conn->sendMsg(jsonString);

        if(returnCode == -1){
            return this->_echoClient(NET::CLIENT_ERROR_SEND_FAILED, "发送失败");
        }else{
            return this->_echoClient(NET::CLIENT_ERROR_SUCCESS, "success");
        }
    }

    clientReturnStruct UserModel::friendList(){
        if(this->uid <= 0){
            return this->_echoClient(NET::CLIENT_ERROR_UNLOGIN, "请先登录");
        }

        Json::Value root, data;
        root["route"] = "user/friendList";
        data["uid"] = this->uid;
        root["data"] = data;

        Json::StreamWriterBuilder builder;
        const std::string jsonString = Json::writeString(builder, root);

        int returnCode = this->conn->sendMsg(jsonString);

        if(returnCode == -1){
            return this->_echoClient(NET::CLIENT_ERROR_SEND_FAILED, "发送失败");
        }else{
            return this->_echoClient(NET::CLIENT_ERROR_SUCCESS, "success");
        }
    }

    clientReturnStruct UserModel::chat(int beuid, std::string msg){
        if(this->uid <= 0){
            return this->_echoClient(NET::CLIENT_ERROR_UNLOGIN, "请先登录");
        }

        Json::Value root, data;
        root["route"] = "user/chat";
        data["uid"] = this->uid;
        data["beuid"] = beuid;
        data["msg"] = msg;
        root["data"] = data;

        Json::StreamWriterBuilder builder;
        const std::string jsonString = Json::writeString(builder, root);
        
        int returnCode = this->conn->sendMsg(jsonString);
        
        if(this->isDebug){
            std::cout << "return code: " << returnCode << std::endl;
        }

        if(returnCode == -1){
            return this->_echoClient(NET::CLIENT_ERROR_SEND_FAILED, "发送失败");
        }else{
            return this->_echoClient(NET::CLIENT_ERROR_SUCCESS, "success");
        }
    }

    std::string UserModel::onRecvMsg(std::string *routeCallback){
        std::string rawJson = this->conn->onRecvMsg();
        if(this->isDebug){
            std::cout << "【onRecvMsg begin】" << std::endl;
            std::cout << rawJson << std::endl;
            std::cout << "【onRecvMsg end】" << std::endl;
        }
        
        // 解析收到的接口返回
        
        const int rawJsonLength = static_cast<int>(rawJson.length());
        JSONCPP_STRING err;
        Json::Value root;

        Json::CharReaderBuilder builder;
        Json::CharReader *reader(builder.newCharReader());
        if(!reader->parse(rawJson.c_str(), rawJson.c_str() + rawJsonLength, &root, &err)){
            std::cout << "parse json error" << std::endl;
        }

        std::string route = root["route"].asString();
        *routeCallback = route;
        if(route == "user/loginCallback"){
            this->loginCallback(root);
        }else if(route == "user/chatCallback"){
            this->chatCallback(root);
        }else if(route == "user/recvChatCallback"){
            // 这个接口是给被接受聊天的玩家的
            this->recvChatCallback(root);
        }else if(route == "user/addFriendCallback"){
            this->addFriendCallback(root);
        }else if(route == "user/friendListCallback"){
            this->friendListCallback(root);
        }else if(route == "user/registeCallback"){
            this->registeCallback(root);
        }

        return rawJson;
    }

    void UserModel::registeCallback(Json::Value root){
        int code = root["code"].asInt();
        if(code == 0){
            int uid = root["data"]["uid"].asInt();
            printf("注册成功，注册uid=%d，请妥善保管UID和密码用于登陆.\n", uid);
        }else{
            std::string msg = root["msg"].asString();
            std::cout << "注册失败，原因如下：" << std::endl;
            std::cout << msg << std::endl;
        }
    }

    void UserModel::loginCallback(Json::Value root){
        int code = root["code"].asInt();
        if(code == 0){
            this->uid = std::stoi(root["data"]["id"].asString());
            std::string username = root["data"]["username"].asString();
            printf("登陆成功,当前uid=%d,昵称=%s\n", this->uid, username.c_str());
        }else{
            std::string msg = root["msg"].asString();
            std::cout << "登陆失败，原因如下：" << std::endl;
            std::cout << msg << std::endl;
        }
    }

    void UserModel::addFriendCallback(Json::Value root){
        int code = root["code"].asInt();
        if(code == 0){
            printf("好友添加成功\n");
        }else{
            std::string msg = root["msg"].asString();
            std::cout << "添加好友失败，原因如下：" << std::endl;
            std::cout << msg << std::endl;
        }
    }

    void UserModel::friendListCallback(Json::Value root){
        int code = root["code"].asInt();
        if(code == 0){
            printf("我的好友\n");
            int listNum = root["data"].size();
            int cssColumnSize = 15;
            printf("==============================\n");
            printf("UID            NAME           \n");
            for(int i = 0; i < listNum; i++){

                // uid
                std::string uid = root["data"][i]["id"].asString();
                printf("%s", uid.c_str());
                for(int j = 0; j< cssColumnSize - uid.size(); j++){
                    printf(" ");
                }
                // name
                std::string name = root["data"][i]["username"].asString();
                printf("%s", name.c_str());
                for(int j = 0; j< cssColumnSize - name.size(); j++){
                    printf(" ");
                }

                printf("\n");
            }

            printf("==============================\n");
        }else{
            std::string msg = root["msg"].asString();
            std::cout << "拉取好友失败，原因如下：" << std::endl;
            std::cout << msg << std::endl;
        }
    }

    void UserModel::chatCallback(Json::Value root){
        int code = root["code"].asInt();
        if(code == 0){
            if(this->isDebug){
                printf("聊天发送成功\n");
            }
        }else{
            std::string msg = root["msg"].asString();
            std::cout << "聊天发送失败，原因如下：" << std::endl;
            std::cout << msg << std::endl;
        }
    }

    void UserModel::recvChatCallback(Json::Value root){
        std::string msg = root["data"]["msg"].asString();
        std::string from_username = root["data"]["from_username"].asString();
        int uid = std::stoi(root["data"]["uid"].asString());
        printf("【%s】说:%s\n", from_username.c_str(), msg.c_str());
    }

    clientReturnStruct UserModel::_echoClient(int code, std::string msg, Json::Value data){
        clientReturnStruct re;
        re.code = code;
        re.msg = "同步接口=>" + msg;
        re.data = data;
        return re;
    }
    
}